#include "_includes.h"

class RainDrop {
public:
  int delta_y = Brain.Screen.getStringHeight("a") * 0.8;
  static const int MAX_N = 25; //最多字母数
  double x, y = 150;           //最下面字母坐标
  double vy;
  char letters[MAX_N];
  int n;
  RainDrop() { generate_rand_parameters(); }

  void generate_rand_parameters() {
    y = 0;
    vy = rand() % 15 + 6;         //速度
    x = rand() % 60 * 8;          //横坐标
    n = rand() % (MAX_N - 5) + 5; //最少5个字母
    create_rand_letters();
    show();
  }

  void create_rand_letters() {
    for (int k = 0; k < n; k++) {
      letters[k] = 'a' + rand() % ('z' - 'a' + 1);
    }
  }

  void show() {
    for (int k = 0; k < n; k++) {
      screen_set_pen_color(color(0, 255 * (n - k - 1) / (double)n, 0)); //颜色值
      Brain.Screen.printAt(x, y - k * delta_y, false, "%c", letters[k]);
    }
  }

  void clear() {
    for (int k = 0; k < n; k++) {
      screen_set_pen_color(black);
      Brain.Screen.printAt(x, y - k * delta_y, false, "%c", letters[k]);
    }
  }

  bool fall_out_of_screen() {
    clear();
    y += vy * 1;
    create_rand_letters();
    show();
    if (y - n * delta_y >= 240) //掉出屏幕以下
      return true;
    else
      return false;
  }
};

void code_drop() {
  Brain.Screen.setFont(mono15);
  RainDrop drops[100];
  while (1) {
    bool all_drops_out_of_screen = true;
    for (auto &r : drops)
      all_drops_out_of_screen *= r.fall_out_of_screen(); //下落并判断
    if (all_drops_out_of_screen)
      return;
    wait(20, msec);
  }
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
fontType font_size[6] = {mono60, mono40, mono30,
                         mono20, mono15, mono12}; //依次变化的字体大小
const fontType init_font = fontType::mono60;
class Letter {
public:
  class Position {
  public:
    double x, y;
    Position() : Position(0, 0) {}
    Position(double xx, double yy) : x(xx), y(yy) {}
    void set_xy(double xx, double yy) { x = xx, y = yy; } //设置坐标
  };

public:
  char c = 0;
  fontType ft = init_font;

  color clr = color(100 + rand() % 155, 100 + rand() % 155,
                    100 + rand() % 155); //随机颜色

  Position p; //字母的中心坐标
  Letter() {}
  Letter(char cc, Position pp) : c(cc), p(pp) { disp(); }

  void set_color(color c) {
    clr = c;
    disp();
  }
  void set_font(fontType ft0) {
    clear();
    ft = ft0;
    disp();
  }
  void set_letter(char c0) {
    clear();
    c = c0;
    disp();
  }
  void pen_set() {
    Brain.Screen.setFont(ft);
    screen_set_pen_color(clr);
  }
  void clear() {
    pen_set(); //恢复成旧状态
    double w = screen_get_font_width(ft);
    double h = screen_get_font_height(ft);
    screen_set_pen_color(sc.brainFillColor); //背景色
    //原始位置覆盖成背景色的文字
    Brain.Screen.printAt(p.x - w / 2.0, p.y + h / 2, false, "%c", c);
    //左右的阴影覆盖
    Brain.Screen.printAt(p.x - w / 2.0 - 1, p.y + h / 2, false, "%c", c);
    Brain.Screen.printAt(p.x - w / 2.0 - 2, p.y + h / 2, false, "%c", c);
    Brain.Screen.printAt(p.x - w / 2.0 + 1, p.y + h / 2, false, "%c", c);
    Brain.Screen.printAt(p.x - w / 2.0 + 2, p.y + h / 2, false, "%c", c);
  }
  void disp() {
    if (c != 0) {
      pen_set(); //更新成新状态
      double w = screen_get_font_width(ft);
      double h = screen_get_font_height(ft);
      Brain.Screen.printAt(p.x - w / 2.0, p.y + h / 2, false, "%c", c);
    }
  }

  void move_for(double dx, double dy) { //移动相对距离
    clear();
    p.set_xy(p.x + dx, p.y + dy);
    disp();
  }

  void move_to(double xx, double yy) { //移动到指定坐标
    clear();
    p.set_xy(xx, yy);
    disp();
  }
};

void set_rand_pen_color() {
  screen_set_pen_color(color(55 + rand() % 200, 55 + rand() % 200,
                             55 + rand() % 200)); //随机颜色
}

//////////////////////////////////////////////////////////////////////////////
#define ALL_RESHOW()                                                           \
  for (auto &r : e)                                                            \
    r.disp();

//动画版本：20220511
void team_num_loading() {
  Letter e[team_name.length()]; //数组
  string c = team_name;

  int max_k = team_name.length();
  double letter_space = screen_get_font_width(init_font) * 0.5; //数字间隔

  double w_letters =
      max_k * screen_get_font_width(init_font) + (max_k - 1) * letter_space;
  while (w_letters > SCREEN_MAX_WIDTH) {
    letter_space--;
    w_letters =
        max_k * screen_get_font_width(init_font) + (max_k - 1) * letter_space;
  } //自动减小过长的队伍名字间距

  int start_x_left = (480 - w_letters) / 2; //左侧坐标
  //第一个数字的中心横坐标
  double x0 = start_x_left + screen_get_font_width(init_font) / 2; //

  const int move_interval = 1;
  //////////////////////////////////第一个，从左到右
  e[0] = Letter(c[0], {0, SCREEN_MAX_HEIGHT / 2});
  for (int x = 0; x <= x0; x++) {
    e[0].move_to(x, e[0].p.y);
    wait(move_interval);
  }
  //////////////////////////////////中间的，上下交错
  for (int k = 1; k <= max_k - 2; k++) {
    ALL_RESHOW();
    int dir;
    x0 += letter_space + screen_get_font_width(init_font);
    if (k % 2 == 0) {
      e[k] = Letter(c[k], {x0, 0});
      dir = 1;
    } else {
      e[k] = Letter(c[k], {x0, SCREEN_MAX_HEIGHT});
      dir = -1;
    }

    for (int i = 0; i <= 59; i++) {
      e[k].move_for(0, dir * 2);
      wait(move_interval);
    }
    wait(10);
  }

  //最后一个，从右到左
  x0 += letter_space + screen_get_font_width(init_font);
  e[max_k - 1] =
      Letter(c[max_k - 1], {SCREEN_MAX_WIDTH, SCREEN_MAX_HEIGHT / 2});
  for (int x = SCREEN_MAX_WIDTH; x >= x0; x--) {
    e[max_k - 1].move_to(x, e[max_k - 1].p.y);
    wait(move_interval);
    ALL_RESHOW();
  }

  ///最后一个,变换
  for (int i = 0; i < 40; i++) {
    char c = rand();
    c = c % 26 + 'A';
    set_rand_pen_color();
    e[max_k - 1].set_letter(c);
    wait(5);
    e[max_k - 1].clear();
    ALL_RESHOW();
  }
  e[max_k - 1].set_letter(c[max_k - 1]);
  timer t;
  while (t.time() < 500) {
    ALL_RESHOW();
    wait(5);
  }

  // 变暗、移动、变小
  for (int i = 0; i < 255; i++) {
    for (int k = 0; k < max_k; k++) {
      e[k].set_color(color(255 - i, 255 - i, 255 - i)); //颜色变暗
      e[k].move_for((max_k - 1) / 2.0 - k, 0);          //向左右两侧移动
      if (i % 43 == 0)                    // 0,43,86,129,172,215,(258)
        e[k].set_font(font_size[i / 43]); // 缩小字体, 6个尺寸
    }
    wait(2);
  }
  wait(300);
}